package cn.jiedanba.cacert.common.ca.crl.tsa;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.Date;

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
import org.bouncycastle.operator.DigestCalculatorProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.tsp.TSPAlgorithms;
import org.bouncycastle.tsp.TSPException;
import org.bouncycastle.tsp.TimeStampRequest;
import org.bouncycastle.tsp.TimeStampResponseGenerator;
import org.bouncycastle.tsp.TimeStampTokenGenerator;

import cn.jiedanba.cacert.common.bc.base.BaseSecurity;
import cn.jiedanba.cacert.common.ca.algorithm.AlgorithmOID;
import cn.jiedanba.cacert.common.ca.crl.tsa.domain.TsaSign;

/**
 * 时间戳签名
 * 
 * @author lenovo
 *
 */
public class PkiTsaUtil extends BaseSecurity {

	/**
	 * 时间戳签名
	 * 
	 * @param hashAlgorithm
	 *            摘要算法
	 * @param signatureAlgorithm
	 *            签名算法
	 * @param tspSigningKey
	 *            时间戳私钥
	 * @param tspSigningCert
	 *            时间戳签名证书
	 * @param encRequest
	 *            待签名的数据
	 * @return
	 * @throws TSPException
	 * @throws OperatorCreationException
	 * @throws GeneralSecurityException
	 * @throws IOException
	 */
	public static byte[] createTspResponse(TsaSign tsaSign)
			throws TSPException, OperatorCreationException, GeneralSecurityException, IOException {
		AlgorithmIdentifier digestAlgorithm = new AlgorithmIdentifier(
				AlgorithmOID.getOidASN1ObjectIdentifier(tsaSign.getHashAlgorithm()));
		DigestCalculatorProvider digProvider = new JcaDigestCalculatorProviderBuilder().setProvider(BC).build();
		TimeStampTokenGenerator tsTokenGen = new TimeStampTokenGenerator(
				new JcaSimpleSignerInfoGeneratorBuilder().build(
						tsaSign.getHashAlgorithm() + "With" + tsaSign.getSignatureAlgorithm(),
						tsaSign.getTspSigningKey(), tsaSign.getTspSigningCert()),
				digProvider.get(digestAlgorithm), new ASN1ObjectIdentifier("1.123.6.1.5.17.23.118"));

		tsTokenGen.addCertificates(new JcaCertStore(Collections.singleton(tsaSign.getTspSigningCert())));

		TimeStampResponseGenerator tsRespGen = new TimeStampResponseGenerator(tsTokenGen, TSPAlgorithms.ALLOWED);

		return tsRespGen.generate(new TimeStampRequest(tsaSign.getEncRequest()),
				tsaSign.getTspSigningCert().getSerialNumber(), new Date()).getEncoded();
	}

}
